package ExpressFive;

import javax.swing.*;
import java.awt.*;

//多级反馈队列
public class MultiRespondQueue {
    //多级队列
    static class QueueDefine<T>{
        private final MyQueue<T>queue;//队列
        private final int runTime;//时间片轮转时间
        public QueueDefine(int runTime){
            queue=new MyQueue<>();
            this.runTime=runTime;
        }
        public void add(T t){
            queue.add(t);
        }
        public T remove(int index){
            return queue.remove(index);
        }
        public T remove(T t){
            return queue.remove(t);
        }
        public T removeHead(){
            return queue.removeHead();
        }
        public T removeTail(){
            return queue.removeTail();
        }
        public T get(int index){
            return queue.get(index);
        }
        public int getRunTime() {
            return runTime;
        }
        public boolean empty(){
            return queue.size() == 0;
        }
        public int size(){return queue.size();}
    }
    private final QueueDefine<MyProcess>q1,q2,q3,q4;//四个队列
    boolean flag=true;
    MultiRespondQueue(){
        q1=new QueueDefine<>(1);//时间片设置为1
        q2=new QueueDefine<>(2);//2
        q3=new QueueDefine<>(4);//3
        q4=new QueueDefine<>(8);//4
    }
    void add(MyProcess process){
        if(process!=null) {
            q1.add(process);
        }
    }
    void run(){
        MyProcess pt;
        while(flag&&(!q1.empty()||!q2.empty()||!q3.empty()||!q4.empty())){
            //进行一些操作
            while(!q1.empty()) {
                //判断是否有新的进程加入，重新开始
                if(!flag){
                    break;
                }

                pt=q1.get(0);
                int index=0;
                for(int i=1;i<q1.size();i++){
                    if(pt.getPriority()<=q1.get(i).getPriority()) {
                        pt=q1.get(i);
                        if (pt.getTime() > q1.get(i).getTime()) {
                            pt = q1.get(i);
                        }
                        index = i;
                    }
                }
                q1.remove(index);

                //pt=q1.removeHead();
                if(!pt.isRunOver(q1.runTime)){
                    q2.add(pt);
                }
                else{
                    q1.remove(pt);
                    JOptionPane.showMessageDialog(null,pt+"is run over(q1)");
                    System.out.println(pt+"is run over(q1)");
                }

            }
            //队列1空，队列2不空
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (flag&&q1.empty() && !q2.empty()){
                // 进行一些操作
                //从q2中获取进程，进行时间片的轮转计算

                while(!q2.empty()) {

                    //判断是否有新的进程加入，重新开始
                    if(!flag){
                        break;
                    }
                    pt=q2.get(0);
                    int index=0;
                    for(int i=1;i<q2.size();i++){
                        if(pt.getPriority()<=q2.get(i).getPriority()) {
                            pt=q2.get(i);
                            if (pt.getTime() > q2.get(i).getTime()) {
                                pt = q2.get(i);
                            }
                            index = i;
                        }
                    }
                    q2.remove(index);
                    //pt=q2.removeHead();
                    if(!pt.isRunOver(q2.runTime)){
                        q3.add(pt);
                    }
                    else{
                        q2.remove(pt);
                        JOptionPane.showMessageDialog(null,pt+"is run over(q2)");

                        System.out.println(pt+"is run over(q2)");
                    }
                }

                //队列1空，队列2空，队列3不空

            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while(flag&&q1.empty()&&q2.empty()&&!q3.empty()){
                //进行一些操作

                while(!q3.empty()) {

                    //判断是否有新的进程加入，重新开始
                    if(!flag){
                        break;
                    }
                    pt=q3.get(0);
                    int index=0;
                    for(int i=1;i<q3.size();i++){
                        if(pt.getPriority()<=q3.get(i).getPriority()) {
                            pt=q3.get(i);
                            if (pt.getTime() > q3.get(i).getTime()) {
                                pt = q3.get(i);
                            }
                            index = i;
                        }
                    }
                    q3.remove(index);
                    //pt=q3.removeHead();
                    if(!pt.isRunOver(q3.runTime)){
                        q4.add(pt);
                    }
                    else{
                        q3.remove(pt);
                        JOptionPane.showMessageDialog(null,pt+"is run over(q3)");

                        System.out.println(pt+"is run over(q3)");
                    }

                }

                //队列4不空
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (flag&&q1.empty()&&q2.empty()&&q3.empty()&&!q4.empty()){
                //进行一些操作
                while(!q4.empty()){
                    if(!flag){
                        break;
                    }
                    pt=q4.get(0);
                    int index=0;
                    for(int i=1;i<q4.size();i++){
                        if(pt.getPriority()<=q4.get(i).getPriority()) {
                            pt=q4.get(i);
                            if (pt.getTime() > q4.get(i).getTime()) {
                                pt = q4.get(i);
                            }
                            index = i;
                        }
                    }
                    q4.remove(index);
                    //pt=q4.removeHead();
                    if(!pt.isRunOver(q4.runTime)){
                        q4.add(pt);
                    }
                    else{
                        q4.remove(pt);
                        JOptionPane.showMessageDialog(null,pt+"is run over(q4)");

                        System.out.println(pt+"is run over(q4)");
                    }
                }
            }
        }
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public QueueDefine<MyProcess> getQ1() {
        return q1;
    }

    public QueueDefine<MyProcess> getQ2() {
        return q2;
    }

    public QueueDefine<MyProcess> getQ3() {
        return q3;
    }

    public QueueDefine<MyProcess> getQ4() {
        return q4;
    }

}
